﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Windows.Threading;
using Microsoft.Phone.Controls;
using PocketBlueBird.ViewModels;
using TweetSharp;

namespace PocketBlueBird
{
    public partial class LoginPage
    {
        private bool _browserLoaded;

        public LoginViewModel _loginViewModel { get; set; }

        public LoginPage()
        {
            InitializeComponent();

            // Uses Alex Yakhnin's configuration implementation:
            // http://blogs.msdn.com/b/priozersk/archive/2010/07/06/app-config-for-wp7-applications.aspx

            if (MainPanoramaPageViewModels.IsAuthorized)
            {
                _loginViewModel = new LoginViewModel(Dispatcher);
            }
            else
            {
                _browser.Visibility = Visibility.Visible;
                _userInfo.Visibility = Visibility.Collapsed;

                _loginViewModel = new LoginViewModel(HandleAuthenticationRequestToken);

                _browser.Navigating += new EventHandler<NavigatingEventArgs>(_browser_Navigating);

                _browser.Loaded += BrowserLoaded;
            }

            this.DataContext = _loginViewModel;
        }

        void _browser_Navigating(object sender, NavigatingEventArgs e)
        {
            if (e.Uri.ToString().Contains(@"callbackuri.html"))
            {
                e.Cancel = true;

                BrowserScriptNotify(_browser, e.Uri.ToString());
            }
        }

        private void BrowserScriptNotify(object sender, string e)
        {
            var values = ParseQueryString(e);
            if (values.ContainsKey("oauth_verifier"))
            {
                var verifier = values["oauth_verifier"];
                _loginViewModel.GetAccessToken(verifier, HandleAuthenticationAccessToken);
            }
            else
            {
                Dispatcher.BeginInvoke(
                    () => new Controls.FadingMessage().ShowTextMessage("Did not authenticate correctly")
                    );
            }
        }

        private void BrowserLoaded(object sender, RoutedEventArgs e)
        {
            _browserLoaded = true;
        }

        /// <summary>
        /// Handles the authentication request token.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="response">The response.</param>
        protected virtual void HandleAuthenticationRequestToken(OAuthRequestToken token, TwitterResponse response)
        {
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                this._loginViewModel.RequestToken = token; // Save the token

                while (!_browserLoaded)
                {
                    Thread.Sleep(200);
                }

                Dispatcher.BeginInvoke(() =>
                    _browser.Navigate(_loginViewModel.GetAuthorizationUri())
                    );
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                    MessageBox.Show(response.InnerException.Message)
                    );
            }
        }

        private void HandleAuthenticationAccessToken(OAuthAccessToken token, TwitterResponse response)
        {
            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                App.AccessToken = token;

                this._loginViewModel.AuthenticateWith();

                Dispatcher.BeginInvoke(
                    () =>
                    {
                        _browser.Visibility = Visibility.Collapsed;
                        _userInfo.Visibility = Visibility.Visible;
                        //this.NavigationService.GoBack();
                    }
                );

                this._loginViewModel.GetUserInfo(Dispatcher);
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show(response.InnerException.Message);
                    this.NavigationService.GoBack();
                });
            }
        }

        public static IDictionary<string, string> ParseQueryString(string query)
        {
            // [DC]: This method does not URL decode, and cannot handle decoded input
            if (query.StartsWith("?")) query = query.Substring(1);

            if (query.Equals(string.Empty))
            {
                return new Dictionary<string, string>();
            }

            var parts = query.Split(new[] { '&' });

            return parts.Select(
                part => part.Split(new[] { '=' })).ToDictionary(
                    pair => pair[0], pair => pair[1]
                );
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (sender is Button)
            {
                Button btn = sender as Button;
                btn.IsEnabled = false;
                this._loginViewModel.LogOut();
                this.NavigationService.Navigate(new Uri("/Views/LoginPage.xaml", UriKind.Relative));
            }
        }
    }
}